package leetcode.dfs;

/**
 * 在显示着数字的坏计算器上，我们可以执行以下两种操作：
 *
 * 双倍（Double）：将显示屏上的数字乘 2；
 * 递减（Decrement）：将显示屏上的数字减 1 。
 * 最初，计算器显示数字 X。
 *
 * 返回显示数字 Y 所需的最小操作数。
 *
 *  
 *
 * 示例 1：
 *
 * 输入：X = 2, Y = 3
 * 输出：2
 * 解释：先进行双倍运算，然后再进行递减运算 {2 -> 4 -> 3}.
 * 示例 2：
 *
 * 输入：X = 5, Y = 8
 * 输出：2
 * 解释：先递减，再双倍 {5 -> 4 -> 8}.
 * 示例 3：
 *
 * 输入：X = 3, Y = 10
 * 输出：3
 * 解释：先双倍，然后递减，再双倍 {3 -> 6 -> 5 -> 10}.
 * 示例 4：
 *
 * 输入：X = 1024, Y = 1
 * 输出：1023
 * 解释：执行递减运算 1023 次
 *  
 *
 * 提示：
 *
 * 1 <= X <= 10^9
 * 1 <= Y <= 10^9
 *
 * 来源：力扣（LeetCode）
 * 链接：https://leetcode-cn.com/problems/broken-calculator
 */
public class 坏了的计算器 {

    public static int brokenCalc(int X, int Y) {
        max = Integer.MAX_VALUE;
        dfs(X, Y, 0);
        return max;
    }

    private static int max;
    public static void dfs(int current, int target, int step){
        if (current == target && step < max){
            max = step;
        }else if(step < max && current > 0){
            if (current < target){
                dfs(current*2, target, step+1);
                dfs(current-1, target, step+1);
            }else {
                dfs(target, target, step+(current-target));
            }
        }
    }

    /**
     *
     * 当Y = XY=X时，返回00
     * 当Y < XY<X时，返回 X-YX−Y
     * 当Y > XY>X 且 YY为奇数时，我们可以得到当前最优序列中倒数第二个数为Y+1Y+1，递归求解到Y+1Y+1的最小操作次数。
     * 当Y > XY>X 且 YY为偶数时, 我们可以得到当前最优序列中倒数第二个数为Y/2Y/2，递归求解到Y/2Y/2的最小操作次数。
     *
     * 作者：KLEA
     * 链接：https://leetcode-cn.com/problems/broken-calculator/solution/tan-xin-suan-fa-ji-qi-zheng-ming-by-lenn123/
     * 来源：力扣（LeetCode）
     * 著作权归作者所有。商业转载请联系作者获得授权，非商业转载请注明出处。
     */
    public static int brokenCalc_1(int X, int Y) {
        if (Y <= X)         return X-Y;
        if (Y % 2 == 0)  return 1 + brokenCalc_1(X, Y/2);
        else                 return 1 + brokenCalc_1(X, Y+1);
    }


    public static void main(String[] args){
        System.out.println(brokenCalc_1(1,1000000000));
    }
}
